package ar.edu.untref.lp1.plomeria.tests.unit;

import org.junit.Assert;
import org.junit.Test;

import ar.edu.untref.lp1.plomeria.helpers.HelperParedDeMaterial;
import ar.edu.untref.lp1.plomeria.modelos.Casillero;
import ar.edu.untref.lp1.plomeria.modelos.Material;
import ar.edu.untref.lp1.plomeria.modelos.Tablero;

public class TableroTest {
	
	public Material[][] getNewWall(int columnas, int filas){
		HelperParedDeMaterial pared = new HelperParedDeMaterial();
		return pared.getParedDeLadrillos(columnas,filas);
	}
	public Material[][] setCañosHorizontalesExtremos(Material[][] pared, int filaIzquierda, int filaDerecha){
		pared[0][filaIzquierda] = Material.CAÑO_HORIZONTAL;
		pared[pared.length - 1][filaDerecha] = Material.CAÑO_HORIZONTAL;
		return pared;
	}
	@Test
	public void crearUnTablero(){
		Material[][] mapaDeMateriales = this.getNewWall(2, 2);
		mapaDeMateriales[0][1] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[1][1] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		Assert.assertNotNull("Crear un tablero",unTablero);
	}
	@Test (expected = Error.class)
	public void crearMalUnTablero(){
		Material[][] mapaDeMateriales = this.getNewWall(2, 2);
		Tablero unTablero = new Tablero(mapaDeMateriales);
	}
	@Test (expected = Error.class)
	public void crearMalUnTableroConCañoIzquierdoSinCañoDerecho(){
		Material[][] mapaDeMateriales = this.getNewWall(5, 2);
		mapaDeMateriales[0][1] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
	}
	@Test (expected = Error.class) 
	public void crearMalUnTableroConCañoDerechoSinCañoIzquierdo(){
		Material[][] mapaDeMateriales = this.getNewWall(5, 2);
		mapaDeMateriales[4][1] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
	}
	@Test (expected = Error.class)
	public void crearMalUnTableroConCañoIntermedioDuplicado(){
		Material[][] mapaDeMateriales = this.getNewWall(5, 5);
		mapaDeMateriales[0][0] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[2][2] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[2][4] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[4][4] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
	}
	@Test (expected = Error.class)
	public void crearMalUnTableroConCañoIntermedioRodeadoDeCaños(){
		Material[][] mapaDeMateriales = this.getNewWall(5, 5);
		mapaDeMateriales[0][0] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[2][2] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[1][1] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[4][4] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
	}
	@Test
	public void asignarMaterialACasilleroDesdeTablero(){
		Material[][] mapaDeMateriales = this.getNewWall(5, 2);
		mapaDeMateriales[0][1] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[4][0] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		unTablero.setMaterialCasillero(Material.CAÑO_ABAJO_DERECHA, 1, 1);
		Assert.assertEquals("Igual Material",Material.CAÑO_ABAJO_DERECHA,unTablero.getMaterialCasillero(1, 1));
	}
	
	@Test 
	public void validarIndiceErrorEnLargoNegativoTest(){
		Material[][] mapaDeMateriales = this.getNewWall(5, 2);
		mapaDeMateriales[0][1] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[4][0] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		Assert.assertFalse(unTablero.validarIndice(23, -1) );
	}
	
	@Test 
	public void validarIndiceMayorQueRangoTest(){
		Material[][] mapaDeMateriales = this.getNewWall(5, 2);
		mapaDeMateriales[0][1] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[4][0] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		Assert.assertFalse(unTablero.validarIndice(23, 5));
	}
	
	@Test
	public void validarIndiceEnRangoTest(){
		Material[][] mapaDeMateriales = this.getNewWall(2, 2);
		mapaDeMateriales[0][0] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[1][1] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		Assert.assertTrue(unTablero.validarIndice(23, 24));
	}
	@Test
	public void obtenerDimensionDeMapaTest(){
		Material[][] mapaDeMateriales = this.getNewWall(2, 3);
		mapaDeMateriales[0][0] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[1][1] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		Assert.assertEquals("Obtiene Columnas totales",2, unTablero.getColumnas());
		Assert.assertEquals("Obtiene Filas totales",3, unTablero.getFilas());
	}
	@Test
	public void obtenerColumnasDelMapaTest(){
		Material[][] mapaDeMateriales = this.getNewWall(4, 4);
		mapaDeMateriales[0][1] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[1][1] = Material.CAÑO_ABAJO_IZQUIERDA;
		mapaDeMateriales[1][2] = Material.CAÑO_VERTICAL;
		mapaDeMateriales[1][3] = Material.CAÑO_ARRIBA_DERECHA;
		mapaDeMateriales[2][3] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[3][3] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		
		Casillero[] columna_indice_1_control = 
			{
				new Casillero(Material.LADRILLO,1,0),
				new Casillero(Material.CAÑO_ABAJO_IZQUIERDA,1,1),
				new Casillero(Material.CAÑO_VERTICAL,1,2),
				new Casillero(Material.CAÑO_ARRIBA_DERECHA,1,3),
			};
		
		Casillero[] columna_indice_1 = unTablero.getColumnaPorIndice(1);
		
		for( int recorreColumna = 0; recorreColumna < mapaDeMateriales.length ; recorreColumna++){
			Assert.assertEquals(
					"validando de la columna 1 la fila "+recorreColumna+" que se correspondan los materiales "
					, columna_indice_1_control[recorreColumna].getMaterial()  , columna_indice_1[recorreColumna].getMaterial()  );
		}
	}
	@Test 
	public void obtenerFilasDelMapaTest(){
		Material[][] mapaDeMateriales = new HelperParedDeMaterial().getParedDeLadrillos(4, 4);
		mapaDeMateriales[0][1] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[1][1] = Material.CAÑO_ABAJO_IZQUIERDA;
		mapaDeMateriales[1][2] = Material.CAÑO_VERTICAL;
		mapaDeMateriales[1][3] = Material.CAÑO_ARRIBA_DERECHA;
		mapaDeMateriales[2][3] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[3][3] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		
		Casillero[] fila_indice_3_control = 
			{
				new Casillero(Material.LADRILLO,0,3),
				new Casillero(Material.CAÑO_ARRIBA_DERECHA,1,3),
				new Casillero(Material.CAÑO_HORIZONTAL,1,3),
				new Casillero(Material.CAÑO_HORIZONTAL,2,3),
				new Casillero(Material.CAÑO_HORIZONTAL,3,3),
			};
		
		Casillero[] fila_indice_3 = unTablero.getFilaPorIndice(3);
		
		for( int recorreFila = 0; recorreFila < mapaDeMateriales.length ; recorreFila++){
			Assert.assertEquals(
					"validando de la fila 3 columna "+recorreFila+" que se correspondan los materiales "
					, fila_indice_3_control[recorreFila].getMaterial()  , fila_indice_3[recorreFila].getMaterial()  );
		}
	}
	
	//auxiliar//
	public void imprimeMapa(){
		Material[][] mapaDeMateriales = this.getNewWall(2, 2);
		Tablero unTablero = new Tablero(mapaDeMateriales);
		for(int x = 0; x < mapaDeMateriales.length ; x++){
			for(int y = 0; y < mapaDeMateriales[0].length ; y++){
				unTablero.setMaterialCasillero(Material.CAÑO_ABAJO_DERECHA, x, y);
				System.out.print("Material: "+unTablero.getMaterialCasillero(x, y));
				System.out.print("Columna: "+x+" | Fila: "+y);
			}
			System.out.println();
		}
	}
	
	@Test
	public void getSiguienteCasilleroDebajo() {
		Material[][] mapaDeMateriales = this.getNewWall(4, 4);
		mapaDeMateriales[0][3] = Material.CAÑO_HORIZONTAL;
		mapaDeMateriales[3][1] = Material.CAÑO_HORIZONTAL;
		Tablero unTablero = new Tablero(mapaDeMateriales);
		Casillero casillero = unTablero.getSiguienteCasilleroDebajo(unTablero.getCasillero(1, 1));
		Assert.assertTrue(casillero.getColumna() == 1 && casillero.getFila() == 2);
	}
}
